/**
 * 所谓层级模型，就是指由多个模型对象以树形结构构成的高级模型对象
 * 就像一个房屋模型、内部的家具、楼梯、门窗等等都各自的模型对象，
 * 组合在一起成为一个整体对象。
 * 这个整体对象就是层级模型
 * 
 * 通过 threejs 提供的方法，我们可以遍历、搜索、操作指定名称或id的子级模型
 * 3D美术人员只需提供最终的整体模型即可
 */
import * as THREE from '../../build/three.module.js';
import dat from '../../jsm/liTree structurebs/dat.gui.module.js';
import {
  OrbitControls
} from '../../jsm/controls/OrbitControls.js';

// 下面简单使用 THREE.Group 构建一个层级模型
const scene = new THREE.Scene();

// 先创建两个网格对象 mesh1 mesh2
const geometry = new THREE.BoxGeometry(20, 20, 20);
const material = new THREE.MeshLambertMaterial({ color: 0x0000ff });
const mesh1 = new THREE.Mesh(geometry, material);
const mesh2 = new THREE.Mesh(geometry, material);
mesh2.translateX(30);
mesh1.name = '模型1'; // 通过 name 属性给模型对象添加标识

// 创建一个层级分组对象
const group = new THREE.Group();

// 将网格模型添加到分组
group.add(mesh1);
group.add(mesh2);
// 与 .add 相对的有个 .remove 方法用于删除指定子级对象
group.name = '分组1'; // 同样 Group 实例也可以通过 name 属性添加标识。

// 再把分组插入场景中
scene.add(group);
/**
 * 在完成分组绑定后，对分组对象进行变换，其内的子模型也会相应的进行变换
 */
// 定义变换对象
const translate = {
  translateY: 0,
  scaleX: 1,
  scaleY: 1,
  scaleZ: 1,
  rotateY: 0
}
/**
 * 场景对象和组对象都有一个 .children 属性用于访问通过 .add 方法添加的子对象
 */
console.log(scene.children, group.children); // 是个数组

const directionalL = new THREE.DirectionalLight(0xffffff, 1);
directionalL.position.set(300, 200, 200);
directionalL.target = group;
scene.add(directionalL);

const axceH = new THREE.AxesHelper(200);
scene.add(axceH);

const k = innerWidth / innerHeight,
      s = 200,
      camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(400, 400, 400);
camera.lookAt(scene.position);

const renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
renderer.setClearColor(0xaaaaaa);
document.body.appendChild(renderer.domElement);

new OrbitControls(camera, renderer.domElement);

// 这是变换值控制
const gui = new dat.GUI({ name: 'translate' });
// gui.add(translate, 'translateY', -100, 100, 1).onFinishChange(translateTranslateY);
gui.add(translate, 'translateY', -100, 100, 1).onChange(translateTranslateY);
gui.add(translate, 'scaleX', .01, 4, .01).onChange(translateScale);
gui.add(translate, 'scaleY', .01, 4, .01).onChange(translateScale);
gui.add(translate, 'scaleZ', .01, 4, .01).onChange(translateScale);
gui.add(translate, 'rotateY', 0, 360, 1).onChange(translateRotate);

// 变换
// 平移
function translateTranslateY() {
  group.translateY(-group.position.y);
  group.translateY(translate.translateY);
}
// 缩放
function translateScale() {
  group.scale.set(translate.scaleX, translate.scaleY, translate.scaleZ);
}
// 旋转
function translateRotate() {
  group.rotateY((translate.rotateY - translateRotate.lastDeg) * (Math.PI / 180));
  translateRotate.lastDeg = translate.rotateY;
}
translateRotate.lastDeg = 0;

function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}
render();